/*
 ------------------------------------------------------------------------------
 Copyright (C) 2009-2011 Eternal Games.

 This file is part of the Eternal Tech source code.

 The Eternal Tech source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Eternal Tech source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Eternal Tech source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// r_public.h - Public header file to all other systems
//


#if !defined(__R_PUBLIC_H__) || !INCLUDE_GUARDS
#define __R_PUBLIC_H__


// Virtual screen dimensions
#define SCREEN_WIDTH				640
#define SCREEN_HEIGHT				480

// Material parms
#define MAX_MATERIAL_PARMS			8

#define MATERIALPARM_RED			0		// Used by "colored" entity materials
#define MATERIALPARM_GREEN			1		// Used by "colored" entity materials
#define MATERIALPARM_BLUE			2		// Used by "colored" entity materials
#define MATERIALPARM_ALPHA			3		// Used by "colored" entity materials
#define MATERIALPARM_TIME_OFFSET	4		// Offset relative to renderView time to control effect start times
#define MATERIALPARM_DIVERSITY		5		// Random value for some effects
#define MATERIALPARM_GENERAL		6		// Used for various things throughout the code
#define MATERIALPARM_MODE			7		// For selecting which material stages to enable

// Render entity types
enum reType_t {
	RE_MODEL,
	RE_SPRITE,
	RE_BEAM
};

// Horizontal adjustment for 2D drawing
enum horzAdjust_t {
	H_NONE,
	H_SCALE,
	H_ALIGN_LEFT,
	H_ALIGN_CENTER,
	H_ALIGN_RIGHT,
	H_STRETCH_LEFT,
	H_STRETCH_WIDTH,
	H_STRETCH_RIGHT
};

// Vertical adjustment for 2D drawing
enum vertAdjust_t {
	V_NONE,
	V_SCALE,
	V_ALIGN_TOP,
	V_ALIGN_CENTER,
	V_ALIGN_BOTTOM,
	V_STRETCH_TOP,
	V_STRETCH_HEIGHT,
	V_STRETCH_BOTTOM
};

struct renderEntity_t {
	reType_t				reType;
	int						renderFX;			// FX flags

	int						index;				// Set by the renderer

	struct model_t			*model;				// Opaque type outside renderer

	int						viewCount;

	// Transformation matrix
	vec3_t					origin;
	vec3_t					axis[3];

	// Model animation data
	int						frame;
	int						oldFrame;

	float					backLerp;			// 0.0 = current, 1.0 = old

	// Sprite specific
	float					spriteRadius;
	float					spriteRotation;
	bool					spriteOriented;		// Use axis for orientation

	// Beam specific
	vec3_t					beamEnd;
	float					beamWidth;
	float					beamLength;			// Segment length

	// Misc stuff
	struct renderView_t		*remoteView;		// For remote cameras

	int						skinIndex;			// Model texturing

	float					depthHack;			// Depth range hack to avoid poking into geometry

	// Material information
	struct material_t		*customMaterial;	// Can be NULL for models

	float					materialParms[MAX_MATERIAL_PARMS];

	// scaling
	float					scale;

	// TODO: Some stuff from the old refdef_t that needs to be replaced
	float					oldorigin[3];
	float					angles[3];
	float					alpha;
	int						flags;

	renderEntity_t()
	{
		scale = 1;
	}
};

struct renderLight_t {
	int						index;				// Set by the renderer

	// Transformation matrix
	vec3_t					origin;
	vec3_t					center;				// Relative to origin
	vec3_t					axis[3];
	vec3_t					radius;

	// Light settings
	int						style;
	int						detailLevel;
	bool					parallel;			// Light center gives the direction to the light at infinity
	bool					noShadows;

	// Material information
	struct material_t		*customMaterial;	// If NULL, _defaultLight will be used

	float					materialParms[MAX_MATERIAL_PARMS];
};

struct renderPolyVertex_t {
	vec3_t				xyz;
	vec3_t				normal;
	vec2_t				st;
	color_t				color;
};

struct renderParticle_t {
	int						index;				// Set by the renderer

	struct material_t	*material;

	// Geometry in triangle-fan order
	int					numVertices;
	renderPolyVertex_t	*vertices;
};

struct renderView_t {
	// Viewport definition
	int						x;
	int						y;
	int						width;
	int						height;

	// Horizontal adjustment
	horzAdjust_t			horzAdjust;
	float					horzPercent;

	// Vertical adjustment
	vertAdjust_t			vertAdjust;
	float					vertPercent;

	// Field of view
	float					fovX;
	float					fovY;

	float					fovScale;

	// Transformation matrix
	vec3_t					viewOrigin;
	vec3_t					viewAxis[3];

	// Current render time
	float					time;

	// Material parms
	float					materialParms[MAX_MATERIAL_PARMS];

	// Area portal bits
	byte					*areaBits;			// If not NULL, only areas with set bits will be drawn

	// TODO: Some stuff from the old refdef_t that needs to be replaced
	float					viewangles[3];
	float					blend[4];
};

struct glConfig_t {
	bool					initialized;

	const char				*vendorString;
	const char				*rendererString;
	const char				*versionString;
	const char				*extensionsString;
	const char				*wglExtensionsString;

	const char				*shadingLanguageVersionString;

	bool					multitexture;
	bool					vertexBufferObject;
	bool					vertexShader;
	bool					fragmentShader;
	bool					shaderObjects;
	bool					textureCubeMap;
	bool					textureNonPowerOfTwo;
	bool					textureCompression;
	bool					textureBorderClamp;
	bool					drawRangeElements;
	bool					textureFilterAnisotropic;
	bool					textureLODBias;
	bool					stencilWrap;
	bool					stencilTwoSide;
	bool					atiSeparateStencil;
	bool					depthBoundsTest;
	bool					swapControl;

	int						maxTextureSize;
	int						max3DTextureSize;
	int						maxCubeMapTextureSize;
	int						maxArrayTextureLayers;
	int						maxTextureUnits;
	int						maxTextureCoords;
	int						maxTextureImageUnits;
	int						maxVertexTextureImageUnits;
	int						maxCombinedTextureImageUnits;
	int						maxVertexAttribs;
	int						maxVaryingComponents;
	int						maxVertexUniformComponents;
	int						maxFragmentUniformComponents;
	int						maxColorAttachments;
	int						maxRenderbufferSize;
	float					maxTextureLODBias;
	float					maxTextureMaxAnisotropy;

	int						videoWidth;
	int						videoHeight;

	bool					deviceSupportsGamma;
	bool					isFullscreen;
	int						displayFrequency;

	int						colorBits;
	int						alphaBits;
	int						depthBits;
	int						stencilBits;

	int						multiSamples;
};

extern glConfig_t			glConfig;

/*
 ==============================================================================

    R_MATERIAL.CPP

 ==============================================================================
*/

struct material_t	*R_RegisterMaterial (const char *name, bool lightingDefault);
struct material_t	*R_RegisterMaterialLight (const char *name);
struct material_t	*R_RegisterMaterialNoMip (const char *name);

void				R_EnumMaterialScripts (void (*callback)(const char *name));

/*
 ==============================================================================

    R_FONT.CPP

 ==============================================================================
*/

#define FONTS_PER_SET				3
#define GLYPHS_PER_FONT				256

#define font_tMALL					0
#define FONT_MEDIUM					1
#define FONT_LARGE					2

struct glyphInfo_t {
	int						image;				// Image index

	int						xAdjust;			// X adjustment
	int						yAdjust;			// Y adjustment

	int						width;				// Width of glyph
	int						height;				// Height of glyph

	float					s1;					// X offset in image where glyph starts
	float					t1;					// Y offset in image where glyph starts
	float					s2;					// X offset in image where glyph ends
	float					t2;					// Y offset in image where glyph ends

	struct material_t		*material;			// The material for the glyph
};

struct fontInfo_t {
	int						maxWidth;
	int						maxHeight;

	int						glyphImages;
	float					glyphScale;

	glyphInfo_t				glyphs[GLYPHS_PER_FONT];
};

struct fontSet_t {
	fontInfo_t				fontInfo[FONTS_PER_SET];
};

fontSet_t			*R_RegisterFont (const char *name);

/*
 ==============================================================================

    R_MODEL.CPP

 ==============================================================================
*/

struct model_t		*R_RegisterModel (const char *name);

/*
 ==============================================================================

    R_LIGHT.CPP

 ==============================================================================
*/

bool				R_EditLight ();

/*
 ==============================================================================

    R_SCENE.CPP

 ==============================================================================
*/

void				R_AddEntityToScene (const renderEntity_t *renderEntity);
void				R_AddLightToScene (const renderLight_t *renderLight);
void				R_AddParticleToScene (const renderParticle_t *renderParticle);
void				R_ResetScene ();

void				R_RenderScene (const renderView_t *renderView, bool primaryView);

/*
 ==============================================================================

    R_WORLD.CPP

 ==============================================================================
*/

void				R_LoadWorldMap (const char *mapName, const char *skyName, float skyRotate, const vec3_t skyAxis);

/*
 ==============================================================================

    R_BACKEND.CPP

 ==============================================================================
*/

void				R_DebugDrawBox (const vec3_t corners[8], const vec3_t color);

/*
 ==============================================================================

    R_MAIN.CPP

 ==============================================================================
*/

glConfig_t			R_GetGLConfig ();
void				R_Activate (bool active);
bool				R_GetVideoModeInfo (int mode, int *width, int *height);
void				R_SetLightStyle (int style, float r, float g, float b);

void				R_DrawStretchPic (float x, float y, float w, float h, float s1, float t1, float s2, float t2, const color_t color, struct material_t *material);
void				R_DrawShearedPic (float x, float y, float w, float h, float s1, float t1, float s2, float t2, float shearX, float shearY, const color_t color, struct material_t *material);

void				R_CropRender (int width, int height, bool makePowerOfTwo);
void				R_UnCropRender ();

void				R_BeginFrame ();
void				R_EndFrame ();

void				R_Init (bool all);
void				R_Shutdown (bool all);


#else
FILE_WARNING
#endif   // __R_PUBLIC_H__